package com.klcw.multithreading.latch;

import java.util.concurrent.CountDownLatch;

/**
 * @ClassName LatchTest
 * @Description 使用闭锁CountDownLatch 实现模拟并发
 * @Author dukang
 * @Date 2019/1/10 10:04
 * @Version 1.0
 **/
public class LatchTest {

    public static void main(String[] args) throws InterruptedException {

        // 创建线程  new Runnable 要使用final修饰
        Runnable testTemp = new Runnable() {

            // 创建一个计数变量    （不安全）
            private int iCounter;
            @Override
            public void run() {
                for (int i = 0 ; i< 10 ;i++){
                    //这里可以使用远程请求
                    iCounter++;
                    System.out.println(System.nanoTime()  + "[" + Thread.currentThread().getName() + "] iCounter =" + iCounter);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        };

        LatchTest latchTest = new LatchTest();
        long time = latchTest.startTaskAllInOnce(5, testTemp);
        System.out.println(time);
    }

    private long startTaskAllInOnce(int threadNums ,final Runnable task) throws InterruptedException {
        // 启动 闭锁CountDownLatch
        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(threadNums);

        // 循环启动线程， 都插入等待状态
        for (int i = 0 ; i < threadNums; i ++){
            Thread t = new Thread() {
                @Override
                public void run() {
                    try {
                        // 让线程进行等待，等开启开始门时 线程一起进入
                        startGate.await();
                        try {
                            task.run();
                        } finally {
                            // 将结束们减1，当减到0时，就可以开启结束门了   finally修饰一定执行
                            endGate.countDown();
                        }
                        endGate.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            // 开启线程
            t.start();
        }
        long startTime = System.nanoTime();
        System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");
        // 只有一个门，所以立即开始开启门
        startGate.countDown();
        endGate.await();
        long endTime = System.nanoTime();
        System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");
        return endTime - startTime;
    }

}
